﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Web;
using System.Web.Script.Serialization;

namespace webfrom_framework.Services
{
    public class AjaxApplication
    {

        private AjaxBasePage m_AjaxBasePage;
        private object m_ResponseData;

        public AjaxApplication(AjaxBasePage ajaxBasePage, AjaxRequest ajaxRequest)
        {
            this.m_AjaxBasePage = ajaxBasePage;
            Type ajaxBasePageType = ajaxBasePage.GetType();
            MethodInfo methodInfo = ajaxBasePageType.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance)
                                        .FirstOrDefault(item => item.Name == ajaxRequest.MethodName);
            object[] parameterData = this.GetParameterData(ajaxRequest, methodInfo);

            if (methodInfo.IsStatic)
            {
                this.m_ResponseData = methodInfo.Invoke(null, parameterData);
            }
            else
            {
                this.m_ResponseData = methodInfo.Invoke(ajaxBasePage, parameterData);
            }
        }

        /// <summary>
        /// 获取参数数据。
        /// </summary>
        private object[] GetParameterData(AjaxRequest ajaxRequest, MethodInfo methodInfo)
        {
            if (methodInfo != null)
            {
                ParameterInfo[] parameterInfos = methodInfo.GetParameters();

                if (parameterInfos.Length > 5)
                {
                    throw new NotSupportedException("最多支持5个参数");
                }

                if (parameterInfos.Length > ajaxRequest.Parameters.Count)
                {
                    throw new ArgumentException("缺少参数!");
                }

                List<object> parameterData = new List<object>(parameterInfos.Length);
                for (int i = 0; i < parameterInfos.Length; i++)
                {
                    ParameterInfo parameterInfo = parameterInfos[i];
                    string paramValue = ajaxRequest.Parameters[i];

                    try
                    {
                        parameterData.Add(ParseAjaxParameter(paramValue, parameterInfo));
                    }
                    catch (FormatException)
                    {
                        string format = string.Format("传入静态方法 {0} 的第 {1} 个（从0开始计数）参数类型不匹配，应该为 {2} 类型 请检查！", methodInfo.Name, i, parameterInfo.ParameterType.Name);
                        throw new FormatException(format);
                    }
                }
                return parameterData.ToArray();
            }
            else
            {
                throw new InvalidOperationException("没有发现此方法，请检查该方法签名（方法必须为public）");
            }
        }

        /// <summary>
        /// 类型转换。支持 String、Boolean、Int32、Int64、UInt32、UInt64、Single、Double、Decimal、DateTime、DateTimeOffset、TimeSpan、Guid
        /// </summary>
        private object ParseAjaxParameter(string ajaxParameterValue, ParameterInfo parameterInfo)
        {
            object obj;
            if (parameterInfo.ParameterType == typeof(String))
            {
                obj = ajaxParameterValue;
            }
            else if (parameterInfo.ParameterType == typeof(Boolean))
            {
                obj = bool.Parse(ajaxParameterValue);
            }
            else if (parameterInfo.ParameterType == typeof(Int32))
            {
                obj = Int32.Parse(ajaxParameterValue);
            }
            else if (parameterInfo.ParameterType == typeof(UInt32))
            {
                obj = UInt32.Parse(ajaxParameterValue);
            }
            else if (parameterInfo.ParameterType == typeof(UInt64))
            {
                obj = UInt64.Parse(ajaxParameterValue);
            }
            else if (parameterInfo.ParameterType == typeof(Single))
            {
                obj = Single.Parse(ajaxParameterValue);
            }
            else if (parameterInfo.ParameterType == typeof(Double))
            {
                obj = Double.Parse(ajaxParameterValue);
            }
            else if (parameterInfo.ParameterType == typeof(Decimal))
            {
                obj = Decimal.Parse(ajaxParameterValue);
            }
            else if (parameterInfo.ParameterType == typeof(DateTime))
            {
                obj = DateTime.Parse(ajaxParameterValue);
            }
            else if (parameterInfo.ParameterType == typeof(DateTimeOffset))
            {
                obj = DateTimeOffset.Parse(ajaxParameterValue);
            }
            else if (parameterInfo.ParameterType == typeof(TimeSpan))
            {
                obj = TimeSpan.Parse(ajaxParameterValue);
            }
            else if (parameterInfo.ParameterType == typeof(Guid))
            {
                obj = Guid.Parse(ajaxParameterValue);
            }
            else
            {
                throw new NotSupportedException("方法参数类型不支持！");
            }
            return obj;
        }

        /// <summary>
        /// 结束页面生命周期，同时直接执行应用程序生命周期的EndRequest事件。
        /// </summary>
        public void EndRequest()
        {
            HttpResponse response = this.m_AjaxBasePage.Page.Response;
            response.ContentType = "application/json";
            response.Clear();
            JavaScriptSerializer jsonSerializer2 = new JavaScriptSerializer();
            response.Write(jsonSerializer2.Serialize(new JsonResponse { IsSuccess = true, Message = "处理成功", ResponseData = this.m_ResponseData }));
            response.End();
        }
    }
}